﻿// 405 二叉树子树和2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>


using  namespace std;
/*
http://oj.daimayuan.top/course/7/problem/459

给你一棵 n个节点的二叉树，节点的编号为 1到 n，二叉树的根为 1 号节点。
每个节点都有一个权值，i号节点的权值为 ai，请求出每个节点的子树的权值和（子树内节点的权值的和）。

输入格式
第一行一个整数 n表示节点数。

接下来 n行，每行两个整数，第一个整数表示 i号节点的左儿子的编号，
第二个整数表示 i号节点的右儿子的编号，如果某个数字为 0表示没有对应的子节点。

输入保证是一棵二叉树。

接下来一行 n个整数，第 i个整数 ai表示 i号节点的权值。

输出格式
输出一行 n个整数，第 i个整数表示 i号节点的子树的权值和。

样例输入
4
2 3
0 0
4 0
0 0
1 1 1 1
样例输出
4 1 2 1
数据规模
对于所有数据，保证 1≤n≤1000000,1≤ai≤100
*/


const int N = 1000000;
struct NODE {
    int l, r, val, fa;
}node[N];
int n;


int GetSum(int x) {
    if (x > n || 0 == x) return 0;

    node[x].val += GetSum(node[x].l) + GetSum(node[x].r);

    return node[x].val;
}


int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int a, b; cin >> a >> b;
        if (a)
            node[i].l = a; node[a].fa = i;
        if (b)
            node[i].r = b; node[b].fa = i;
    }
    for (int i = 1; i <= n; i++) {
        int t; cin >> t;
        node[i].val = t;
    }

    GetSum(1);

    for (int i = 1; i <= n; i++) {
        cout << node[i].val << " ";
    }

    return 0;
}
